using System;
using System.Drawing;
using SuperListEx.WinFormsUtility.Drawing;

namespace SuperListEx.Sections
{
  public class CellSection : Section
  {
    #region vars
    private HeaderColumnSection _hcs;
    private object _item;
    #endregion

    #region properties
    public HeaderColumnSection HeaderColumnSection
    {
      get
      {
        return _hcs;
      }
      set
      {
        _hcs = value;
      }
    }

    public virtual object Item
    {
      get
      {
        return _item;
      }
      set
      {
        _item = value;
      }
    }

    protected virtual object DisplayItem
    {
      get
      {
        object o;

        if (_hcs.Column.ColumnItemAccessor != null)
        {
          o = _hcs.Column.ColumnItemAccessor(_item);
        }

        else
        {
          o = _hcs.Column.ColumnItemAccessorWithParameter(_item, _hcs.Column.AccessorParameter);
        }

        if (o == null)
        {
          o = "(null)";
        }
        return o;
      }
    }

    protected Rectangle DrawRectangle
    {
      get
      {
        Rectangle rcScrollAdjusted = HostBasedRectangle;
        Rectangle rc = new Rectangle(rcScrollAdjusted.X + 5,
                                     rcScrollAdjusted.Y + 2,
                                     rcScrollAdjusted.Width - 5,
                                     rcScrollAdjusted.Height - 2);
        return rc;
      }
    }

    protected Color ForeColor
    {
      get
      {
        return ((RowSection)Parent).ItemForegroundColor;
      }
    }

    protected Color BackgroundColor
    {
      get
      {
        return ((RowSection)Parent).ItemBackgroundColor;
      }
    }

    protected virtual Font Font
    {
      get
      {
        if (this.Parent != null)
          return ((RowSection)Parent).ItemFont;
        else
          return SystemFonts.DefaultFont;
      }
    }

    protected string DisplayItemString
    {
      get
      {
        string s = "";
        if (HeaderColumnSection.Column.ColumnItemFormattedAccessor == null)
        {
          s = DisplayItem.ToString();
        }
        else
        {
          s = HeaderColumnSection.Column.ColumnItemFormattedAccessor(Item).ToString();
        }

        s = s.Replace(Environment.NewLine, " ");
        s = s.Replace("\r\n", " ");
        return s;
      }
    }

    protected Alignment GdiExAlignment
    {
      get
      {
        switch (_hcs.Column.Alignment)
        {
          case Alignment.Left:
            return Alignment.Left;
          case Alignment.Center:
            return Alignment.Center;
          case Alignment.Right:
            return Alignment.Right;
          default:
            return Alignment.Left;
        }
      }
    }

    protected VerticalAlignment GdiExVerticalAlignment
    {
      get
      {
        return _hcs.Column.VerticalAlignment;
      }
    }

    protected internal RowSection RowSection
    {
      get
      {
        return (RowSection)Parent;
      }
    }

    protected ListSection ListSection
    {
      get
      {
        return (ListSection)Parent.Parent;
      }
    }
    #endregion

    #region constructors
    public CellSection(ISectionHost host, HeaderColumnSection hcs, object item)
      : base(host)
    {
      _hcs = hcs;
      _item = item;
    }
    #endregion

    #region public functions
    public override void Layout(GraphicsSettings gs, Size maximumSize)
    {
      const int margin = 2;
      SizeF size;
      if (HeaderColumnSection.Column.WrapText)
      {
        size = GdiPlusEx.MeasureString(gs.Graphics, DisplayItemString, Font, maximumSize.Width - 5);
      }
      else
      {
        size = gs.Graphics.MeasureString(DisplayItemString, Font);
      }
      if (size.Height < MinimumHeight)
      {
        size.Height = MinimumHeight;
      }
      Size = new Size(maximumSize.Width, (int)size.Height + margin * 2);
    }

    public virtual Size GetIdealSize(GraphicsSettings gs)
    {
      const int margin = 2;
      SizeF size = gs.Graphics.MeasureString(DisplayItemString, Font);
      return new Size((int)size.Width + 4, (int)size.Height + margin * 2);
    }

    public override void Paint(GraphicsSettings gs, Rectangle clipRect)
    {
      Rectangle rc = DrawRectangle;
      GdiPlusEx.DrawString
        (gs.Graphics,
         DisplayItemString,
         Font,
         (Host.FocusedSection == ListSection && RowSection.IsSelected) ? SystemColors.HighlightText : ForeColor,
         rc,
         GdiExAlignment, GdiExVerticalAlignment,
         GdiPlusEx.TextSplitting.SingleLineEllipsis, GdiPlusEx.Ampersands.Display);
    }
    #endregion
  }
}